#include "eapplication.h"
#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>
#include <QDebug>

#include "resources/etexturemanager.h"
#include "graphics/egraphicsobjectmanager.h"
#include "input/einputmanager.h"

#include "graphics/egraphicsobject.h"
#include "graphics/esprite.h"

EApplication::EApplication(QObject *parent) :
    QObject(parent)
  , m_bRunning(false)
  , m_fPrevTime(0)
  , m_fPhysicsScaleFactor(50.0f)
  , m_basicResolution(800, 600)
{

}

EApplication &EApplication::app()
{
    static EApplication inst;
    return inst;
}

bool EApplication::init(int resWidth, int resHeight,bool bFullscreen)
{
    bool rValue = true;

    SDL_Init(SDL_INIT_EVERYTHING);
    //IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);

    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    SDL_SetVideoMode(resWidth, resHeight, 32, SDL_OPENGL | (bFullscreen ? SDL_FULLSCREEN : 0));

    m_resolutionScale.setX((float)resWidth/(float)m_basicResolution.x());
    m_resolutionScale.setY((float)resHeight/(float)m_basicResolution.y());

    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_PROJECTION);
    glOrtho(0, resWidth, resHeight, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    rValue = initManagers();

    if(rValue)
    {
        m_bRunning = true;
    }
    else
    {
        return false;
    }

    return rValue;
}

void EApplication::destroy()
{

}

void EApplication::update(float dt)
{
    m_inputManager->update();
}

void EApplication::render()
{

}

void EApplication::run()
{
    SDL_Event event;

    while(m_bRunning)
    {
        float thisTime = (float)SDL_GetTicks();
        float dt = (float)(thisTime - m_fPrevTime)/1000;
        m_fPrevTime = thisTime;

        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT)
            {
                m_bRunning = false;
                break;
            }

            if (event.type == SDL_KEYDOWN)
            {
                if(event.key.keysym.sym == SDLK_ESCAPE)
                {
                    m_bRunning = false;
                    break;
                }
            }

            //m_input->handleMouseEvents(event);
        }

        update(dt);
        render();
    }
}

bool EApplication::initManagers()
{
    m_textureManager.reset(new ETextureManager);
    m_graphicsObjectManager.reset(new EGraphicsObjectManager(m_textureManager));
    m_inputManager.reset(new EInputManager);

    return m_textureManager && m_graphicsObjectManager
            && m_inputManager;
}

boost::shared_ptr<ETextureManager> EApplication::textureManager() const
{
    return m_textureManager;
}

boost::shared_ptr<EGraphicsObjectManager> EApplication::graphicsObjectManager() const
{
    return m_graphicsObjectManager;
}

boost::shared_ptr<EInputManager> EApplication::inputManager() const
{
    return m_inputManager;
}

float EApplication::toGraphicsCoordinates(float value)
{
    return value*m_fPhysicsScaleFactor;
}

float EApplication::toPhysicsCoordinates(float value)
{
    return value/m_fPhysicsScaleFactor;
}

const QPointF &EApplication::resoultionScale() const
{
    return m_resolutionScale;
}
